package org.hive.testserver.domain.model;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.SortedMap;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.CompareToBuilder;

public class TestSummary implements Comparable<TestSummary> {
	
	private long averageDuration;
	private String testRunId;
	private String testRunName;
	private String name;
	private TestState currentState;
	private int timesExecuted;
	private List<TestExecutionSummary> executions = new ArrayList<TestExecutionSummary>();
	private boolean isFinished;
	private long started;

	public static class TestExecutionSummary {
		private TestState currentStatus;
		private String slave;
		private long started;
		private SortedMap<String,String> resultContext;
		private String scheduledReason;

		public TestExecutionSummary(ExecuteTest work) {
			super();
			currentStatus = StringUtils.isBlank(work.result) ? TestState.RUNNING : TestState.valueOf(work.result());
			slave = work.assignedSlave().getName();
			started = work.started();
			resultContext = work.resultContext();
			scheduledReason = work.scheduledReason();
		}

		public TestState getCurrentStatus() {
			return currentStatus;
		}

		public String getSlave() {
			return slave;
		}

		public long getStarted() {
			return started;
		}
		
		public String getScheduleReason() {
			return scheduledReason;
		}

		public SortedMap<String,String> resultContext() {
			return Collections.unmodifiableSortedMap(resultContext);
		}
	}
	
	public TestSummary(Test test, Collection<Work> works) {
		super();
		name = test.getName();
		averageDuration = test.averageDuration();
		currentState = test.currentState();
		timesExecuted = test.timesExecuted();
		isFinished = test.isFinished();
		testRunId = test.getTestRun().getId();
		testRunName = test.getTestRun().getName();
		started = Long.MAX_VALUE;
		initializeFromWorks(works);
	}

	private void initializeFromWorks(Collection<Work> works) {
		for (Work work : works) {
			if (work instanceof ExecuteTest) {
				ExecuteTest executeTest = (ExecuteTest) work;
				executions.add(new TestExecutionSummary(executeTest));
				started = Math.min(started, work.started()); 
			}
		}
	}
	
	public long getAverageDuration() {
		return averageDuration;
	}

	public String getName() {
		return name;
	}

	public TestState getCurrentState() {
		return currentState;
	}

	public int getTimesExecuted() {
		return timesExecuted;
	}

	public List<TestExecutionSummary> getExecutions() {
		return executions;
	}

	public int compareTo(TestSummary o) {
		return new CompareToBuilder().append(getName(), o.getName()).append(started, o.started).toComparison();
	}

	public boolean isFinished() {
		return isFinished;
	}

	public String testRunId() {
		return testRunId;
	}

	public long getStarted() {
		return started;
	}

	public String getTestRunName() {
		return testRunName;
	}

}
